﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using TheVerge.Base.Platform;
using TheVerge.Base;

namespace TheVerge.Base.Models
{
    public class VMComments : AVM
    {
        public long ArticleId
        {
            get { return GetValue(() => ArticleId); }
            private set { SetValue(value, () => ArticleId); }
        }

        public string ErrorMessage
        {
            get { return GetValue(() => ErrorMessage); }
            set { SetValue(value, () => ErrorMessage); }
        }

        public VMComment[] Comments
        {
            get { return GetValue(() => Comments); }
            set { 
                SetValue(value, () => Comments);
                Notify(() => HasComments);
            }
        }

        public bool HasComments
        {
            get { return Comments != null && Comments.Length > 0; }
        }

        public void Load(long articleId)
        {
            ArticleId = articleId;
            API.GetComments(ArticleId, result =>
            {
                if (result == null)
                {
                    OnLoadingCommentsError("Results was null");
                    return;
                }

                InitializeComments(result.AllComments.Select(c => c.Comment).ToList());

            }, error => OnLoadingCommentsError(error.Message));
        }

        private void InitializeComments(IList<Comment> list)
        {
            //-- Initialize a dictionary first to make it easy to find comments
            var comments = new Dictionary<long, Comment>();
            foreach (var c in list)
            {
                comments[c.Id] = c;
            }

            //-- Now iterate over all of the comments, setting up parents and finding the root comments
            var rootReplies = new List<Comment>();
            foreach (var c in list)
            {
                if (c.ParentId.HasValue && comments.ContainsKey(c.ParentId.Value))
                {
                    comments[c.ParentId.Value].Replies.Add(c);
                    c.Parent = comments[c.ParentId.Value];
                }
                else
                    rootReplies.Add(c);
            }

            //-- Now that we've setup all of the relationships, we need to create a flat list that can be displayed to the user
            var flat_list = new List<VMComment>();
            foreach (var c in rootReplies.OrderBy(rc => rc.CreatedOn))
            {
                var commentVM = new VMComment(ArticleId, c);
                flat_list.Add(commentVM);
                AddChildren(flat_list, commentVM);
            }

            Comments = flat_list.ToArray();
        }

        private void AddChildren(List<VMComment> allReplies, VMComment parent)
        {
            foreach (var reply in parent.Replies.OrderBy(r => r.CreatedOn))
            {
                allReplies.Add(reply);
                AddChildren(allReplies, reply);
            }
        }

        private void OnLoadingCommentsError(string message)
        {
            ErrorMessage = message;
            UI.ShowMessage(message);
        }
    }
}